package com.sk.bilibili.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sk.bilibili.bean.Favorites;
import com.sk.bilibili.bean.Type;
import com.sk.bilibili.dto.CollectInfo;
import com.sk.bilibili.event.BiliBiliEvent;
import com.sk.bilibili.other.R;
import com.sk.bilibili.utils.BSessionUtils;
import com.sk.bilibili.utils.QueryWrapperUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
import com.sk.bilibili.bean.Collect;
import com.sk.bilibili.mapper.CollectMapper;

import java.util.*;
import java.util.stream.Collectors;

/**
* @author 邵康
* @date 2021/11/25 15:36
*/
@Service
public class CollectService extends ServiceImpl<CollectMapper, Collect> {

    @Autowired
    private FavoritesService favoritesService;
    @Autowired
    private VideoSetService videoSetService;
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    @Autowired
    private TypeService typeService;

    public R<Collect> add(Collect collect) {
        int memberId = BSessionUtils.getMemberId();
        collect.setMemberId(memberId);
        if(collect.getFavoritesId()==null){
            collect.setFavoritesId(favoritesService.getDefaultFavorites(memberId));
        }
        save(collect);
        eventPublisher.publishEvent(new BiliBiliEvent<>(this, collect));
        return R.success(collect);
    }

    public R<Void> delete(Integer id) {
        Collect collect = getById(id);
        eventPublisher.publishEvent(new BiliBiliEvent<>(this, collect));
        removeById(id);
        return R.success();
    }

    public R<Void> update(Collect collect) {
        eventPublisher.publishEvent(new BiliBiliEvent<>(this, collect));
        updateById(collect);
        return R.success();
    }

    public R<IPage<Collect>> pageType(CollectInfo collectInfo) {
        Page<Collect> page = baseMapper.pageType(collectInfo.page(), collectInfo);
        page.getRecords().forEach(this::warpVideoSet);
        return R.success(page);
    }

    private void warpVideoSet(Collect collect) {
        collect.getExtra().addExtra(videoSetService.getBaseVideoSet(collect.getVideoSetId()));
    }

    public R<IPage<Collect>> pageSearch(CollectInfo collectInfo) {
        List<Integer> ids=getFavoritesIds(collectInfo);
        Page<Collect> page = baseMapper.pageSearch(collectInfo.page(), ids, collectInfo.getKeyword());
        page.getRecords().forEach(this::warpVideoSet);
        return R.success(page);
    }

    private List<Integer> getFavoritesIds(CollectInfo collectInfo) {
        if(collectInfo.getFavoritesId()==null){
            R<List<Favorites>> all = favoritesService.getAll(null, null);
            return all.getData().stream().map(Favorites::getId).collect(Collectors.toList());
        }else {
            return Collections.singletonList(collectInfo.getFavoritesId());
        }
    }

    public void removeCollect(Integer id) {
        QueryWrapper<Collect> queryWrapper = QueryWrapperUtils.eq("favorites_id", id);
        remove(queryWrapper);
    }

    public R<Void> copy(Integer[] ids, Integer favoritesId) {
        Collection<Collect> list = listByIds(Arrays.asList(ids));
        for (Collect collect:list){
            collect.setFavoritesId(favoritesId);
            save(collect);
        }
        return R.success();
    }

    public Collect getCollect(int memberId, Integer videoSetId) {
        QueryWrapper<Collect> queryWrapper = QueryWrapperUtils.eq("member_id", memberId,
                "video_set_id", videoSetId);
        return getOne(queryWrapper);
    }

    public R<List<Type>> getPageType(Integer favoritesId) {
        List<Map<String,Long>> list=baseMapper.getPageType(favoritesId);
        List<Type> res=typeService.getTypeList(list);
        return R.success(res);
    }

}
